Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[microNPU] Add MergeConstants pass #12029

Merged
merged 4 commits into from
Jul 12, 2022

Conversation

NicolaLancellotti
Copy link

@NicolaLancellotti NicolaLancellotti commented Jul 7, 2022

This pr adds a MergeConstants pass that looks for the constants used by each compute operator and merges them into a single buffer.

@manupa-arm @ekalda @lhutton1

cc @Mousius

Nicola Lancellotti added 2 commits July 7, 2022 08:49
Change-Id: I1ff51d8147fba8c66d442a370b9f058e9b2758d8
Change-Id: I29f68f83a73fa00ca34ed0ab2321c53c6b761137
@github-actions github-actions bot requested a review from Mousius July 7, 2022 13:24
Copy link
Contributor

@manupak manupak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @NicolaLancellotti !

I have a done a round of reviews. There are few things we should improve in the PR. See if you agree.

Also please consider adding docs for non-trivial functions.

We need to align with coding style of TVM : https://tvm.apache.org/docs/contribute/code_guide.html
(I have put a few specific comments to each type)

@@ -90,6 +90,8 @@ def lower_ethosu(sch, args, const_dict, name="main"):
mod = tvm.tir.transform.RemoveNoOp()(mod)
mod, const_dict = ethosu_passes.EncodeConstants(const_dict)(mod)
mod = ethosu_passes.HoistAllocates()(mod)
if not util.is_striping_enabled():
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please leave a comment that MergeConstant pass currently does not support striped schedules and requires further investigation.

new_const_dict = {}
for param in const_dict.keys():
new_const_dict[tvm.tir.IntImm("int64", param)] = tvm.nd.array(const_dict[param])
mod["main"] = mod["main"].with_attr("ethos-u.const-dict", new_const_dict)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit : lets stick to const_dict

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

analyze = false;
new_body = rewrite_prim_func_body(new_body);
std::set<ObjectRef> params_to_delete{};
auto new_buffer_map{make_new_buffer_map(main_func->buffer_map, &params_to_delete)};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lets not use auto here.
it is fine to use auto when you can understand the type from just looking at the line. In this case, one need to look into the function.

Quote from from the following :
"For example, you can assume that the return type of make_unique() is obvious, but the return type of MyWidgetFactory() probably isn't."

Reference : https://google.github.io/styleguide/cppguide.html#Type_deduction

(Applies to all the lines)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.


// Rewrite new allocates
for (auto it{copy_write_buffers.rbegin()}; it != copy_write_buffers.rend(); ++it) {
if (auto buffer_opt = *it) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets use the type here.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Constants written to a buffer with local scope are not merged.
"""

def mergeConstantsPass(mod):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Style : this should be lower case. https://peps.python.org/pep-0008/#function-and-variable-names

(Only exception is the Passes because we want them aligned with C++ ones and I think the from API PoV the accessible pass function should be MergeConstants)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.


PrimFunc operator()(PrimFunc main_func, const Map<IntImm, runtime::NDArray>& const_dict) {
// Analyze
Stmt new_body{this->VisitStmt(main_func->body)};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is generally a not good practice to mix analysis and transformation in a single pass.
E.g. for analysis pass : (https://github.com/apache/tvm/blob/main/src/tir/usmp/analysis/extract_buffer_info.cc)
However, since this is simpler analysis we can keep the analysis pass internal to this source.

Can we break this out to a new pass (in this source file) that return the analysis information and run the sub-sequent pass to rewrite w/o resorting to a mode variable analyze ?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

if (op->size() <= 1) {
return StmtExprMutator::VisitStmt_(op);
}
return analyze ? analyze_seq_stmt(op) : rewrite_seq_stmt(op);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refer to the above comment about seperation of analysis and transformation passes.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

std::map<const VarNode*, Allocate> var_to_allocate{};

// Rewrite old allocates
std::set<ObjectRef> buffer_vars{get_vars_for_written_copy_buffers()};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need a ordered set here ? (Noting that ordered_set's access time is higher)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I switched to unordered_set.

for (size_t i{0}; i < seq_stmt.size(); ++i) {
Stmt stmt{seq_stmt[i]};

switch (get_stmt_type(stmt)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is a switch on an enumerated value, and all cases are covered. So we don't need a default, don't we?

for (size_t i = 0; i < seq_stmt.size(); ++i) {
Stmt stmt{seq_stmt[i]};

switch (get_stmt_type(stmt)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is a switch on an enumerated value, and all cases are covered. So we don't need a default, don't we?

@manupak manupak self-assigned this Jul 8, 2022
Change-Id: Iad59107d5abdec6b079c6fd4ab48c6bffbb5e0bb
@NicolaLancellotti
Copy link
Author

Thanks @NicolaLancellotti !

I have a done a round of reviews. There are few things we should improve in the PR. See if you agree.

Also please consider adding docs for non-trivial functions.

We need to align with coding style of TVM : https://tvm.apache.org/docs/contribute/code_guide.html (I have put a few specific comments to each type)

Thanks for the review @manupa-arm!

Change-Id: Ie5caf506337de01e169d6f422e4682eefbd93241
Copy link
Contributor

@manupak manupak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@manupak manupak merged commit fbf80bb into apache:main Jul 12, 2022
@manupak
Copy link
Contributor

manupak commented Jul 12, 2022

Thanks @NicolaLancellotti !

masahi pushed a commit to masahi/tvm that referenced this pull request Jul 15, 2022
* [microNPU] Add MergeConstants pass

Change-Id: I1ff51d8147fba8c66d442a370b9f058e9b2758d8

* Fix errors and warnings

Change-Id: I29f68f83a73fa00ca34ed0ab2321c53c6b761137

* Address comments

Change-Id: Iad59107d5abdec6b079c6fd4ab48c6bffbb5e0bb

* Fix lint error

Change-Id: Ie5caf506337de01e169d6f422e4682eefbd93241
junrushao pushed a commit to yelite/tvm that referenced this pull request Jul 27, 2022
* [microNPU] Add MergeConstants pass

Change-Id: I1ff51d8147fba8c66d442a370b9f058e9b2758d8

* Fix errors and warnings

Change-Id: I29f68f83a73fa00ca34ed0ab2321c53c6b761137

* Address comments

Change-Id: Iad59107d5abdec6b079c6fd4ab48c6bffbb5e0bb

* Fix lint error

Change-Id: Ie5caf506337de01e169d6f422e4682eefbd93241
xinetzone pushed a commit to daobook/tvm that referenced this pull request Nov 25, 2022
* [microNPU] Add MergeConstants pass

Change-Id: I1ff51d8147fba8c66d442a370b9f058e9b2758d8

* Fix errors and warnings

Change-Id: I29f68f83a73fa00ca34ed0ab2321c53c6b761137

* Address comments

Change-Id: Iad59107d5abdec6b079c6fd4ab48c6bffbb5e0bb

* Fix lint error

Change-Id: Ie5caf506337de01e169d6f422e4682eefbd93241
mikeseven pushed a commit to mikeseven/tvm that referenced this pull request Sep 27, 2023
* [microNPU] Add MergeConstants pass

Change-Id: I1ff51d8147fba8c66d442a370b9f058e9b2758d8

* Fix errors and warnings

Change-Id: I29f68f83a73fa00ca34ed0ab2321c53c6b761137

* Address comments

Change-Id: Iad59107d5abdec6b079c6fd4ab48c6bffbb5e0bb

* Fix lint error

Change-Id: Ie5caf506337de01e169d6f422e4682eefbd93241
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants